package com.ubird.tetris.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import com.ubird.demo.TetrisDemo;
import com.ubird.tetris.block.TetrisBlock;
import com.ubird.ui.DrawUtil;

public class ScorePanel extends JPanel {

    private static final long serialVersionUID = 1251179527381938354L;
    private Image bg = null;

    private Color fontColor = new Color(255, 200, 200);

    String[] tips = { " [A] or [LEFT] : move left", "[S] or [DOWN] : move down", "[D] or [RIGHT] : move right",
            " [W] or [UP] : rotate", "[P] or [ENTER] : pause", " [ESC] : restart" };
    private Color tipShadowColor = new Color(0, 150, 255);

    private TetrisBlock nextBlock;
    private int score;
    private final static int[] ALTER_SCORES = { 10, 20, 40, 80 };

    private Color versionAndAuthorColor = new Color(255, 255, 255);
    private int currDrawScore;

    private int lightIndex = 0;
    private int[][] lightPoses = { { 137, 285, 236, 346 }, { 137, 285, 236, 346 }, { 137, 285, 236, 346 },
            { 137, 285, 236, 346 }, { 137, 285, 236, 346 }, { 137, 346, 236, 407 }, { 137, 346, 236, 407 },
            { 137, 346, 236, 407 }, { 137, 346, 236, 407 }, { 137, 346, 236, 407 }, { 137, 346, 236, 407 },
            { 137, 407, 236, 468 }, { 137, 407, 236, 468 }, { 137, 407, 236, 468 }, { 137, 407, 236, 468 },
            { 137, 346, 236, 407 }, { 137, 346, 236, 407 }, { 137, 346, 236, 407 }, { 137, 346, 236, 407 },
            { 137, 346, 236, 407 }, { 137, 346, 236, 407 }, { 137, 285, 236, 346 }, { 137, 285, 236, 346 },
            { 137, 285, 236, 346 }, { 137, 285, 236, 346 }, { 137, 285, 236, 346 } };

    private static Image TETRIS_RES = null;
    static {
        try {
            TETRIS_RES = ImageIO.read(ScorePanel.class.getClassLoader().getResource("com/ubird/ui/res/Tetris.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public ScorePanel(int width, int height) {
        this.setPreferredSize(new Dimension(width, height));
        try {
            bg = ImageIO.read(getClass().getClassLoader().getResource("com/ubird/ui/res/bg.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void addScore(int[] disLine) {
        if (disLine != null && disLine.length > 0) {
            this.score += ALTER_SCORES[Math.min(disLine.length, ALTER_SCORES.length) - 1];
            if (this.score > getMaxScore())
                clearScore();
        }
    }

    public void clearScore() {
        this.score = 0;
        this.currDrawScore = 0;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        paintBg(g);
        paintSplit(g);
        paintVersionAndAuthor(g);
        paintScore(g);
        // paintNextBlock(g);
        paintTips(g, 10, 530);
    }

    private void paintVersionAndAuthor(Graphics g) {
        DrawUtil.drawShadowString(g, TetrisDemo.VERSION + " by " + TetrisDemo.AUTHOR, 12, 78, 90, 3,
                versionAndAuthorColor, fontColor);
    }

    private void paintSplit(Graphics g) {
        g.draw3DRect(0, 0, 2, getHeight(), true);
    }

    private void paintBg(Graphics g) {
        if (bg != null) {
            g.drawImage(bg, 0, 0, getWidth(), getHeight(), null);
        } else {
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, (int) getWidth(), (int) getHeight());
        }
    }

    private void paintScore(Graphics g) {
        int width = 338 - 255;
        int height = 463 - 205;
        int dx = (getWidth() - width) / 2;
        g.drawImage(TETRIS_RES, dx, 250, dx + width, 250 + height, 255, 205, 338, 463, null);
        g.drawImage(TETRIS_RES, dx, (int) (250 + height * (1 - currDrawScore / getMaxScore())), dx + width,
                250 + height, 350, (int) (463 - height * currDrawScore / getMaxScore()), 432, 463, null);

        int lsx1 = lightPoses[lightIndex][0];
        int lsy1 = lightPoses[lightIndex][1];
        int lsx2 = lightPoses[lightIndex][2];
        int lsy2 = lightPoses[lightIndex][3];
        int ldw = lsx2 - lsx1;
        int ldh = lsy2 - lsy1;
        int ldx1 = dx + (width - ldw) / 2;
        int scoreYFix = 0;
        if (score > 0 & score < getMaxScore())
            scoreYFix = 10;
        else if (score >= getMaxScore())
            scoreYFix = 30;
        int ldy1 = (int) (463 - height * currDrawScore / getMaxScore() + scoreYFix);
        int ldx2 = ldx1 + ldw;
        int ldy2 = ldy1 + ldh;
        g.drawImage(TETRIS_RES, ldx1, ldy1, ldx2, ldy2, lsx1, lsy1, lsx2, lsy2, null);

        if (currDrawScore < score)
            currDrawScore += (score - currDrawScore) / 2;
        currDrawScore = Math.min(currDrawScore, score);
        lightIndex = (lightIndex + 1) % lightPoses.length;
    }

    private float getMaxScore() {
        return 200;
    }

    private void paintNextBlock(Graphics g) {
        if (nextBlock != null) {
            nextBlock.draw(g, 20);
        }
    }

    public void setNextBlock(TetrisBlock nextBlock) {
        this.nextBlock = nextBlock.copy();
        this.nextBlock.init((int) (getPreferredSize().getWidth() / 70), 8);
    }

    public void paintTips(Graphics g, int x, int y) {
        int fontSize = 12;
        int fontHeight = 18;
        int shadowWidth = 3;

        int maxWidth = 0;
        Font f = new Font("宋体", Font.PLAIN, fontSize);
        FontMetrics fontMetrics = g.getFontMetrics(f);
        for (int i = 0; i < tips.length; i++) {
            String[] split = tips[i].split(":");
            int newWidth = (int) fontMetrics.getStringBounds(split[0], g).getWidth();
            maxWidth = maxWidth > newWidth ? maxWidth : newWidth;
        }
        for (int i = 0; i < tips.length; i++) {
            String[] split = tips[i].split(":");
            int newWidth = (int) fontMetrics.getStringBounds(split[0], g).getWidth();
            maxWidth = maxWidth > newWidth ? maxWidth : newWidth;
            DrawUtil.drawShadowString(g, f, split[0], x + maxWidth - newWidth, y + i * fontHeight, shadowWidth,
                    tipShadowColor, fontColor);
            DrawUtil.drawShadowString(g, f, split[1], x + maxWidth, y + i * fontHeight, shadowWidth, tipShadowColor,
                    fontColor);
        }
    }
}